package cn.kgc.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.apache.curator.framework.recipes.locks.InterProcessReadWriteLock;
import org.apache.curator.framework.recipes.locks.InterProcessSemaphoreV2;
import org.apache.curator.framework.recipes.locks.Lease;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

/**
 * 使用Curator框架实现分布式锁
 *
 * @author YC
 */
@RequestMapping("/curator")
@RestController
@Api(tags = "Curator分布式锁")
public class CuratorController {

    @Resource
    private CuratorFramework curatorFramework;

    @GetMapping("/lock1")
    public String lock1() throws Exception {
        InterProcessMutex mutex = new InterProcessMutex(curatorFramework, "/myLock");
        // 尝试获得锁，最多5秒
        boolean acquire = mutex.acquire(5, TimeUnit.SECONDS);
        if (acquire) {
            System.out.println("获得锁");
            // 如果获得锁，模拟业务执行耗时10秒
            Thread.sleep(10000);
            // 释放锁
            mutex.release();
            System.out.println("释放锁");
        } else {
            System.out.println("未获得锁");
        }
        return "success";
    }

    /**
     * 读读不互斥，读写互斥
     */
    @ApiOperation(value = "获得读锁")
    @GetMapping("/lock2")
    public String lock2() throws Exception {
        InterProcessReadWriteLock lock = new InterProcessReadWriteLock(curatorFramework, "/myReadWriteLock");
        InterProcessMutex readLock = lock.readLock();
        boolean acquire = readLock.acquire(5, TimeUnit.SECONDS);
        if (acquire) {
            System.out.println("获得读锁");
            Thread.sleep(10000);
            readLock.release();
            System.out.println("释放读锁");
        } else {
            System.out.println("未获得读锁");
        }
        return "success";
    }

    @ApiOperation(value = "获得写锁")
    @GetMapping("/lock3")
    public String lock3() throws Exception {
        InterProcessReadWriteLock lock = new InterProcessReadWriteLock(curatorFramework, "/myReadWriteLock");
        InterProcessMutex writeLock = lock.writeLock();
        boolean acquire = writeLock.acquire(5, TimeUnit.SECONDS);
        if (acquire) {
            System.out.println("获得写锁");
            Thread.sleep(10000);
            writeLock.release();
        }
        System.out.println("释放写锁");
        return "success";
    }

    @ApiOperation(value = "获得信号量")
    @GetMapping("/semaphore")
    public String semaphore() throws Exception {
        InterProcessSemaphoreV2 semaphore = new InterProcessSemaphoreV2(curatorFramework, "/mySemaphore", 5);
        Lease lease = semaphore.acquire(5, TimeUnit.SECONDS);
        if (lease != null) {
            System.out.println("获得信号量");
            Thread.sleep(5000);
            semaphore.returnLease(lease);
        }
        System.out.println("释放信号量");
        return "success";
    }

}
